/***************************************************************
*Copyright(c) 2020思特诺(Stduino)All right reserved.
*
*This library is open source and free for individual users. 
*
*For commercial use, please contact service001@stduino.com.
***************************************************************/

#ifndef String_class_h
#define String_class_h
#ifdef __cplusplus

#include "StduinoMemory.h"
#include "StduinoStringFuction.h"

class StringSumHelper;
class String
{
public:
 String(const char *cstr = "");
 String(const String &str);
 explicit String(char c);
 explicit String(unsigned char, unsigned char=DEC);
 explicit String(int, unsigned char=DEC);
 explicit String(unsigned int, unsigned char=DEC);
 explicit String(long, unsigned char=DEC);
 explicit String(unsigned long, unsigned char=DEC);
 explicit String(float, unsigned char=1);
 explicit String(double, unsigned char=2);
 ~String(void);
 unsigned char reserve(unsigned int size);
 inline unsigned int length(void) const {return len;}
 String & operator = (const String &rhs);
 String & operator = (const char *cstr);
 unsigned char concat(const String &str);
 unsigned char concat(const char *cstr);
 unsigned char concat(char c);
 unsigned char concat(unsigned char c);
 unsigned char concat(int num);
 unsigned char concat(unsigned int num);
 unsigned char concat(long num);
 unsigned char concat(unsigned long num);
 unsigned char concat(float num);
 unsigned char concat(double num);
 String & operator += (const String &rhs)
 {
  concat(rhs);
  return (*this);
 }
 String & operator += (const char *cstr)
 {
  concat(cstr); 
  return (*this);
 }
 String & operator += (char c)
 {
  concat(c); 
  return (*this);
 }
 String & operator += (unsigned char num)
 {
  concat(num); 
  return (*this);
 }
 String & operator += (int num)
 {
  concat(num); 
  return (*this);
 }
 String & operator += (unsigned int num)
 {
  concat(num); 
  return (*this);
 }
 String & operator += (long num)
 {
  concat(num); 
  return (*this);
 }
 String & operator += (unsigned long num)
 {
  concat(num); 
  return (*this);
 }
 String & operator += (float num)
 {
  concat(num); 
  return (*this);
 }
 String & operator += (double num)
 {
  concat(num); 
  return (*this);
 }
 friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
 friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
 friend StringSumHelper & operator + (const StringSumHelper &lhs, char c);
 friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num);
 friend StringSumHelper & operator + (const StringSumHelper &lhs, int num);
 friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
 friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
 friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
 friend StringSumHelper & operator + (const StringSumHelper &lhs, float num);
 friend StringSumHelper & operator + (const StringSumHelper &lhs, double num);
 int compareTo(const String &s) const;
 unsigned char equals(const String &s) const;
 unsigned char equals(const char *cstr) const;
 unsigned char operator == (const String &rhs) const {return equals(rhs);}
 unsigned char operator == (const char *cstr) const {return equals(cstr);}
 unsigned char operator != (const String &rhs) const {return !equals(rhs);}
 unsigned char operator != (const char *cstr) const {return !equals(cstr);}
 unsigned char operator <  (const String &rhs) const;
 unsigned char operator >  (const String &rhs) const;
 unsigned char operator <= (const String &rhs) const;
 unsigned char operator >= (const String &rhs) const;
 unsigned char equalsIgnoreCase(const String &s) const;
 unsigned char startsWith( const String &prefix) const;
 unsigned char startsWith(const String &prefix, unsigned int offset) const;
 unsigned char endsWith(const String &suffix) const;
 char charAt(unsigned int index) const;
 void setCharAt(unsigned int index, char c);
 char operator [] (unsigned int index) const;
 char& operator [] (unsigned int index);
 void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const;
 void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const 
 {
  getBytes((unsigned char *)buf, bufsize, index);
 }
 const char * c_str() const
 {
  return buffer;
 }
 char* begin()
 {
  return buffer;
 }
 char* end()
 {
  return buffer + length();
 }
 const char* begin() const
 {
  return c_str();
 }
 const char* end() const
 {
  return c_str() + length();
 }
 int indexOf( char ch ) const;
 int indexOf( char ch, unsigned int fromIndex ) const;
 int indexOf( const String &str ) const;
 int indexOf( const String &str, unsigned int fromIndex ) const;
 int lastIndexOf( char ch ) const;
 int lastIndexOf( char ch, unsigned int fromIndex ) const;
 int lastIndexOf( const String &str ) const;
 int lastIndexOf( const String &str, unsigned int fromIndex ) const;
 String substring( unsigned int beginIndex ) const
 {
  return substring(beginIndex, len);
 };
 String substring( unsigned int beginIndex, unsigned int endIndex ) const;
 void replace(char find, char replace);
 void replace(const String& find, const String& replace);
 void remove(unsigned int index);
 void remove(unsigned int index, unsigned int count);
 void toLowerCase(void);
 void toUpperCase(void);
 void trim(void);
 long toInt(void) const;
 float toFloat(void) const;
 double toDouble(void) const;
protected:
 char *buffer;
 unsigned int capacity;
 unsigned int len;
protected:
 void init(void);
 void invalidate(void);
 unsigned char changeBuffer(unsigned int maxStrLen);
 unsigned char concat(const char *cstr, unsigned int length);
 String & copy(const char *cstr, unsigned int length);
};

class StringSumHelper : public String
{
public:
 StringSumHelper(const String &s) : String(s) {}
 StringSumHelper(const char *p) : String(p) {}
 StringSumHelper(char c) : String(c) {}
 StringSumHelper(unsigned char num) : String(num) {}
 StringSumHelper(int num) : String(num) {}
 StringSumHelper(unsigned int num) : String(num) {}
 StringSumHelper(long num) : String(num) {}
 StringSumHelper(unsigned long num) : String(num) {}
 StringSumHelper(float num) : String(num) {}
 StringSumHelper(double num) : String(num) {}
};

#endif

#endif

/***************************************************************
*Copyright(c) 2020思特诺(Stduino)All right reserved.
*
*This library is open source and free for individual users. 
*
*For commercial use, please contact service001@stduino.com.
***************************************************************/
